using System;
using System.Collections.Generic;
using System.Text;
using Hoshimi._NanoRobots_;
using System.Drawing;
using Hoshimi._Map_;
using PH.Common;
using Hoshimi._Utilitaire_;
using Hoshimi._Map_._Zone_;

namespace Hoshimi
{
	public class WallGroup : Group
	{
		public override bool Add(Unit unit)
        {
            WallBot bot = (WallBot)unit;
			
		    // We affect a brain to the unit
		    bot.InitStateMachine( WallBotSMFactory.Instance() );

            return base.Add(unit);
        }

		/// <summary>
		/// Check the life of the unit
		/// </summary>
		/// <returns>Return true</returns>
		public override bool IsAlive()
		{
			base.IsAlive();

            return true;
		}

		public void DeclareNewWallBuild(BaseWall nanobot)
		{
			this.AskBot(BotTypeEnum.BaseWall);
		}

		public bool IsLocationBlocked(Point location)
		{
			if(this.myChilds.Count <= 0)
			{
				return false;
			}

			foreach(WallBot bot in this.myChilds)
			{
				if(bot.WallZoneContains(location))
				{
					return true;
				}
			}

			return false;
		}

		public bool IsAlreadyWallInZone(Point wallLocation)
		{
			if(this.myChilds.Count <= 0)
			{
				return false;
			}

			CircleZone circleZone = new CircleZone(wallLocation, Config.WallLength);
			foreach(WallBot bot in this.myChilds)
			{
				if(bot.IntectectWallZone(circleZone))
				{
					return true;
				}
			}

			return false;
		}

		public bool IsInterestingBuildingWall(Point wallLocation)
		{
			if(this.IsAlreadyWallInZone(wallLocation))
			{
				return false;
			}

			if(this.IsBlockingEnnemies(wallLocation))
			{
				return true;
			}

			return false;
		}
		
		public bool IsBlockingEnnemies(Point wallLocation)
		{
			// On regarde si on block des ennemis
			int nbEnnemyBlocked = 0;
			foreach (EnnemyStatus ennemyStatus in myMapManager.myEnnemyStatus.Values)
            {
				// On ne veut pas blocker les bots de pierre, on les fuit :)
				if(ennemyStatus.IsPierreBot())
				{
					continue;
				}

				// Type de bot que l'on veut bloquer
				if(	!ennemyStatus.IsNanoMoveable())
				{
					continue;
				}

				// Sera t'il pris dans le wall?
				if(!(IsInWallPerimeter(wallLocation, ennemyStatus.myLocation) ||
					 IsInWallPerimeter(wallLocation, ennemyStatus.GetPredictedLocation(Config.NbPredictTurnUseForWallAndBlocker))))
                {
                    continue;
                }

				// Bloquer le nanoAI de l'adversaire est une occasion en or
				if (ennemyStatus.IsNanoBotType(NanoBotType.NanoAI))
				{
					return true;
				}

				nbEnnemyBlocked++;
            }

			return (nbEnnemyBlocked >= Config.MinBlockedEnnemies);
		}

		public static bool IsInWallPerimeter(Point wallLocation, Point location)
		{
			int squareDist = Utilitaire.SquareDistance(wallLocation, location);
            return (squareDist <= Config.WallLengthSquare);
		}

		public override bool ReleaseUnit()
		{
			float minCoeff			= int.MinValue;
			WallBot uselessBot	= null;
			float useCoeff;
			foreach(WallBot bot in this.myChilds)
			{
				useCoeff = bot.GetUseCoeff();
				
				if(useCoeff < minCoeff)
				{
					minCoeff	= useCoeff;
					uselessBot	= bot;
				}
			}

			if(uselessBot == null)
			{
				return false;
			}

			this.Remove(uselessBot);
			uselessBot.ForceAutoDestruction();

			return true;
		}

		public override int GetFreeBotCount()
		{
			int uselessCount = 0;
			float useCoeff;
			foreach(WallBot bot in this.myChilds)
			{
				useCoeff = bot.GetUseCoeff();

				if (useCoeff <= 0)
				{
					uselessCount++;
				}
			}

			return uselessCount;
		}

		#region Ctor

        // Inhibate the default constructor
        protected WallGroup() { }

		/// <summary>
		/// Constructor
		/// </summary>
		/// <param name="player">Environment</param>
		/// <param name="aFactory">Factory used to build the state machine</param>
		public WallGroup(Component myFather, AbstractSMFactory aFactory ) 
            : base(myFather, aFactory ) 
        {

        } 

        #endregion
	}
}